﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Configuration;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Routing;
using System.Text;

namespace ESB
{
    class Router :IDisposable
    {
        private string baseAddress = @"http://localhost:4975/";
        private List<string> servicesAdresses = new List<string>();
        private ServiceHost routingHost;

        public Router()
        {
            servicesAdresses.Add("http://localhost:2344/");
        }

        public void Start()
        {
            routingHost = new ServiceHost(typeof (RoutingService));
            
            AddSimpleEndpoint();
            AddMexEndpoint();
            var configuration = new RoutingConfiguration();

            var metadataEndpoints = new ServiceEndpoint[]
                                        {
                                            new ServiceEndpoint(
                                                ContractDescription.GetContract(typeof (IRequestReplyRouter)),
                                                MetadataExchangeBindings.CreateMexHttpBinding(),
                                                new EndpointAddress(servicesAdresses[0] + "mex")),
                                        };
            metadataEndpoints[0].Behaviors.Add(new MetadataBehavior());
            var serviceEndpoints = new ServiceEndpoint[]
                                       {
                                           new ServiceEndpoint(
                                               ContractDescription.GetContract(typeof (IRequestReplyRouter)),
                                               new WSHttpBinding(),
                                               new EndpointAddress(servicesAdresses[0])
                                               ),
                                       };


        
            configuration.FilterTable.Add(new EndpointAddressMessageFilter(new EndpointAddress("http://localhost:4975/mex")), metadataEndpoints, 2);
            configuration.FilterTable.Add(new MatchAllMessageFilter(),serviceEndpoints,1);

            routingHost.Description.Behaviors.Add(new RoutingBehavior(configuration));

            routingHost.Open();
        }


        ContractDescription contract = ContractDescription.GetContract(typeof(IRequestReplyRouter));
        public void AddSimpleEndpoint()
        {
            
            Binding binding = new WSHttpBinding();
            EndpointAddress address = new EndpointAddress(baseAddress);
            ServiceEndpoint endpoint = new ServiceEndpoint(contract, binding, address);
            routingHost.AddServiceEndpoint(endpoint);
        }

        private void AddMexEndpoint()
        {
            Binding binding = MetadataExchangeBindings.CreateMexHttpBinding();
            EndpointAddress address = new EndpointAddress(baseAddress+"/mex");
            ServiceEndpoint endpoint = new ServiceEndpoint(contract, binding, address);
            routingHost.AddServiceEndpoint(endpoint);
        }

        public void Dispose()
        {
            if (routingHost != null) 
                routingHost.Close();
        }
    }
}
